/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.lcm.metadata.core;

import com.inspur.edp.lcm.metadata.common.FileServiceImp;
import com.inspur.edp.lcm.metadata.common.configuration.MavenSettingsLoader;
import com.inspur.edp.lcm.metadata.common.logging.MvnStreamConsumer;
import com.inspur.edp.lcm.metadata.core.exception.MvnExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.utils.cli.CommandLineException;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhaoleitr
 */
@Slf4j
public class MavenUtilsCore {
	private String mavenHomePath;

	private final DefaultInvoker invoker;

	private final InvocationRequest request;

	private final MvnStreamConsumer mvnStreamConsumer;

    private String errorMessage;

	public MavenUtilsCore(){
		invoker = new DefaultInvoker();
		request = new DefaultInvocationRequest();
		mvnStreamConsumer = new MvnStreamConsumer();
	}

	public  boolean exeMavenCommand(String javaCodePath, String mavenPath, String goal) {
		initInvoker();

		invoker.setWorkingDirectory(new File(javaCodePath));

		List<String> goals = handleGoul(goal, mavenPath);
		request.setGoals(goals);

		try {
			mvnStreamConsumer.setExceptionString("");
			InvocationResult result = invoker.execute(request);
			int resultNum = result.getExitCode();
			if (resultNum == 0) {
				return true;
			}

			if (resultNum == 1) {
				final String exceptionString = mvnStreamConsumer.getExceptionString();
				if (!exceptionString.isEmpty()) {
					MvnExceptionHandler mvnExceptionHandler = new MvnExceptionHandler();
					errorMessage = "";
					errorMessage = mvnExceptionHandler.handleMessage(exceptionString);
					errorMessage = errorMessage.isEmpty() ? "maven编译失败，具体错误请参考日志服务[ERROR]部分" : errorMessage;
				}

				CommandLineException executionException = result.getExecutionException();
				if (executionException != null) {
					throw executionException;
				}
				return false;
			}
		} catch (Exception e) {
			log.error("执行maven命令失败",e);
			e.printStackTrace();
		}
		return false;
	}

	public String getLocalRepository(){
		try {
			String localRepository = MavenSettingsLoader.getSettings().getLocalRepository();
			if (localRepository != null) {
				return localRepository;
			}
		} catch (IOException | XmlPullParserException e) {
			throw new RuntimeException("获取maven本地仓库地址出错，请检查settings.xml配置",e);
		}
		return null;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	private void initMavenHomePath() {
		if (!StringUtils.isEmpty(mavenHomePath)) {
			return;
		}

		if (System.getenv("MAVEN_HOME") != null) {
			mavenHomePath = System.getenv("MAVEN_HOME");
		} else if (System.getenv("M2_HOME") != null){
			mavenHomePath = System.getenv("M2_HOME");

			invoker.setMavenHome( new File(System.getenv("M2_HOME")));
		} else {
			String systemPath = System.getenv("Path");
			if (systemPath != null) {
				String[] paths = systemPath.split("\\;");
				for (String path : paths) {
					if (path.contains("maven")) {
						mavenHomePath = path.substring(0,path.length()-4);
					}
				}
			}
		}
		if (StringUtils.isEmpty(mavenHomePath)) {
			throw new IllegalArgumentException("请配置maven环境变量！MAVEN_HOME=....");
		}
	}

	private List<String> handleGoul(String goal,String mavenPath) {
		List<String> goals = new ArrayList<>();

		StringBuilder goalSb = new StringBuilder(goal);
		String settingsPath = mavenPath + File.separator + "config" + File.separator + "settings.xml";
		FileServiceImp fileService=new FileServiceImp();
		if (fileService.isFileExist(settingsPath)) {
			goalSb.append(" -s ").append(settingsPath);
		} else {
			log.warn("配置文件" + settingsPath + "不存在，使用默认settings.xml配置");
		}

		goals.add(goalSb.toString());
		return goals;
	}

	private void initInvoker() {
		initMavenHomePath();
		invoker.setMavenHome(new File(mavenHomePath));
		request.setOutputHandler(mvnStreamConsumer).setBatchMode(true);
	}
}
